﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Settings;
using System.Threading;
using FileCopier;
using System.IO;

namespace MASSBAckUp
{
    public partial class CopyForm : Form, ILoggger
    {
        private class ThreadWorker
        {
            private MassStorageDevice Device;
            private CopyForm Form;

            public ThreadWorker(MassStorageDevice Device, CopyForm Form)
            {
                this.Device = Device;
                this.Form = Form;
            }

            public delegate void StringDeligate(String Text);
            public delegate void LogDeligate(String Text, LogType type);
            public delegate void NoParameters();

            public void RunMe()
            {
                try
                {
                    foreach (Object ob in Device.folders)
                    {
                        SyncFolder sf = (SyncFolder)ob;

                        string masks = "";
                        foreach (String mask in sf.Masks)
                        {
                            if (masks.Length == 0) 
                                masks = mask;
                            else
                                masks = masks +", " + mask;
                        }

                        AddStringToLog("Поиск файлов по маске: " + masks + " в папке " + sf.Path);

                        String SourcePath = System.IO.Path.Combine( Device.ActualDiskLetter + ":\\", sf.Path );
                         SourcePath = Device.ActualDiskLetter + ":\\" + sf.Path;

                        List<String> files =
                            FileFinder.FileFinder.GetFilesByMask(SourcePath,
                            sf.Masks.Cast<String>());

                        FileCopier.FileCopier.CopyFiles(files, sf.DestinationFolder, sf.SType, sf.CType, Form, sf.FolderTemplate);

                    }

                    Form.LogsText.Invoke(new NoParameters(Form.Complete));
                }
                catch (ThreadAbortException /*e*/)
                {

                }
            }

            public void AddStringToLog(String Text, LogType type = LogType.NormalLog)
            {
                Form.AddStringToLog(Text, type);
            }

        }

        private MassStorageDevice Device;
        private Thread t = null;
        private bool CancelButtonWasPressed = false;

        public CopyForm(MassStorageDevice Device)
        {
            this.Device = Device;
            InitializeComponent();
        }

        private void CopyForm_Load(object sender, EventArgs e)
        {
            ThreadWorker tw = new ThreadWorker(Device, this);
            t = new Thread(tw.RunMe);
            t.Start();
        }

        public void Complete()
        {
            OkButton.Enabled = true;
            Cancel.Enabled = false;
            LogsText.AppendText("\nCompleted!\n");
        }

        public delegate void StringDeligate(String Text);


        #region interface ILoggger

        public void AddStringToLog(String Text, LogType type = LogType.NormalLog)
        {
            if (this.InvokeRequired)
            {
                Invoke(new AddStringToLogWorkerDelegate(AddStringToLogWorker), new Object[] { Text + "\n", type });
            }
            else
            {
                AddStringToLogWorker(Text, type);
            }
        }

        

        private delegate void AddStringToLogWorkerDelegate(String Text, LogType type = LogType.NormalLog);
        private void AddStringToLogWorker(String Text, LogType type = LogType.NormalLog)
        {
            Color Old = LogsText.SelectionColor;
            switch (type)
            {
                case LogType.Error:
                    {
                        LogsText.SelectionColor = Color.Red;
                    }break;
                case LogType.Warning:
                    {
                        LogsText.SelectionColor = Color.Blue;
                    }break;
            }

            LogsText.AppendText(Text + "\n");
            LogsText.SelectionColor = Old;
        }

        private delegate CopyConflictResolution CopyConflictDelegate(FileInfo Src, FileInfo Dst);
        public CopyConflictResolution CopyConflict(FileInfo Src, FileInfo Dst)
        {
            if (this.InvokeRequired)
            {
                IAsyncResult result = this.BeginInvoke(new CopyConflictDelegate(CopyConflictWorker), new Object[] {Src, Dst });
                return (CopyConflictResolution)this.EndInvoke(result);
            }

                return CopyConflictWorker(Src, Dst);         
        }

        private CopyConflictResolution CopyConflictWorker(FileInfo Src, FileInfo Dst)
        {
            FileReplaceForm frf = new FileReplaceForm(Src, Dst);
            frf.ShowDialog();
            return new CopyConflictResolution(frf.Resolution);
        }

        #endregion

        private void OkButton_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
            Close();
        }

        private void CopyForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (CancelButtonWasPressed)
            {
                e.Cancel = false;
                return;
            }
            e.Cancel = !CheckThatWorkCanBeCompleted();
            if (!e.Cancel)
            {
                StopThread();
            }
        }

        private void StopThread()
        {
            t.Abort();
            t.Join();
        }

        private bool CheckThatWorkCanBeCompleted()
        {
            if (t.IsAlive)
            {
                const string message = "Копирование файлов все еще не завершино.\nПрервать?";
                const string caption = "Остановка копирования...";
                var result = MessageBox.Show(message, caption,
                                             MessageBoxButtons.YesNo,
                                             MessageBoxIcon.Question);

                if (result == DialogResult.No)
                {
                    return false;
                }

                return true;

            }
            return true;
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            if (CheckThatWorkCanBeCompleted())
            {
                CancelButtonWasPressed = true;
                DialogResult = DialogResult.Cancel;
                StopThread();
                Close();
            }
        }
    }
}
